/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using IQIGame.Onigao.Framework;
using System.Collections.Generic;
using System.Linq;
using System;
using NetProtocol.Enum;

namespace NetProtocol.POD {

	/// <summary>
	/// 
	/// module : levelLogic
	/// </summary>
	public class LevelSavePOD : IPOD 
    {
        public readonly static Func<LevelSavePOD> FACTORY = () => new LevelSavePOD();
		public static Func<LevelSavePOD> DynamicFactory = FACTORY;
        
		/*-- members --*/
		/// <summary>
        /// 
        /// </summary>
		public int idGenerator;
		/// <summary>
        /// 
        /// </summary>
		public long randomSeed;
		/// <summary>
        /// 
        /// </summary>
		public int levelFrame;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<long, LevelPlayerSavePOD> m_playerSaves;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<int, LevelRegionSavePOD> m_regionSaves;
		/// <summary>
        /// 
        /// </summary>
        private Dictionary<int, int> m_levelParams;
		/// <summary>
        /// 
        /// </summary>
        private List<DelayServicePOD> m_delayServices;
		/// <summary>
        /// 
        /// </summary>
		public int timeHour;
		/// <summary>
        /// 
        /// </summary>
		public int cid;
		/// <summary>
        /// 
        /// </summary>
		public long hostPlayerId;
		/// <summary>
        /// 
        /// </summary>
		public long id;
		
		
        public Dictionary<long, LevelPlayerSavePOD> playerSaves
        {
            get
            {
                if(m_playerSaves == null)
                {
                    m_playerSaves = new();
                }
                return m_playerSaves;
            }
            private set => m_playerSaves = value;
        }
        public Dictionary<long, LevelPlayerSavePOD> unsafe_playerSaves
        {
        	get => m_playerSaves;
        	set => m_playerSaves = value;
        }
        public Dictionary<int, LevelRegionSavePOD> regionSaves
        {
            get
            {
                if(m_regionSaves == null)
                {
                    m_regionSaves = new();
                }
                return m_regionSaves;
            }
            private set => m_regionSaves = value;
        }
        public Dictionary<int, LevelRegionSavePOD> unsafe_regionSaves
        {
        	get => m_regionSaves;
        	set => m_regionSaves = value;
        }
        public Dictionary<int, int> levelParams
        {
            get
            {
                if(m_levelParams == null)
                {
                    m_levelParams = new();
                }
                return m_levelParams;
            }
            private set => m_levelParams = value;
        }
        public Dictionary<int, int> unsafe_levelParams
        {
        	get => m_levelParams;
        	set => m_levelParams = value;
        }
        public List<DelayServicePOD> delayServices
        {
            get
            {
                if(m_delayServices == null)
                {
                    m_delayServices = new();
                }
                return m_delayServices;
            }
            private set => m_delayServices = value;
        }
        public List<DelayServicePOD> unsafe_delayServices
        {
        	get => m_delayServices;
        	set => m_delayServices = value;
        }
		
		/*-- constructors --*/
		public LevelSavePOD() {}
		public LevelSavePOD(int idGenerator, long randomSeed, int levelFrame, Dictionary<long, LevelPlayerSavePOD> playerSaves, Dictionary<int, LevelRegionSavePOD> regionSaves, Dictionary<int, int> levelParams, List<DelayServicePOD> delayServices, int timeHour, int cid, long hostPlayerId, long id) {
			this.idGenerator = idGenerator;
			this.randomSeed = randomSeed;
			this.levelFrame = levelFrame;
			this.m_playerSaves = playerSaves;
			this.m_regionSaves = regionSaves;
			this.m_levelParams = levelParams;
			this.m_delayServices = delayServices;
			this.timeHour = timeHour;
			this.cid = cid;
			this.hostPlayerId = hostPlayerId;
			this.id = id;
		}
		  public void Serial(SOutputStream _out) {
                if(idGenerator != default) {
                    _out.WriteByte(1);
                    _out.Write_int(idGenerator);
                }
                if(randomSeed != default) {
                    _out.WriteByte(2);
                    _out.Write_long(randomSeed);
                }
                if(levelFrame != default) {
                    _out.WriteByte(3);
                    _out.Write_int(levelFrame);
                }
                if(m_playerSaves != default) {
                    _out.WriteByte(4);
                    _out.Write_map_long_pod(m_playerSaves);
                }
                if(m_regionSaves != default) {
                    _out.WriteByte(5);
                    _out.Write_map_int_pod(m_regionSaves);
                }
                if(m_levelParams != default) {
                    _out.WriteByte(6);
                    _out.Write_map_int_int(m_levelParams);
                }
                if(m_delayServices != default) {
                    _out.WriteByte(7);
                    _out.Write_list_pod(m_delayServices);
                }
                if(timeHour != default) {
                    _out.WriteByte(8);
                    _out.Write_int(timeHour);
                }
                if(cid != default) {
                    _out.WriteByte(9);
                    _out.Write_int(cid);
                }
                if(hostPlayerId != default) {
                    _out.WriteByte(10);
                    _out.Write_long(hostPlayerId);
                }
                if(id != default) {
                    _out.WriteByte(11);
                    _out.Write_long(id);
                }
        }
            
        public void UnSerial(SInputStream _in) {
            while (_in.HasRemaining())
            {
                int _key = _in.ReadByte();
                switch (_key)
                {
                    case 1:
                        idGenerator = _in.Read_int();
                        break;
                    case 2:
                        randomSeed = _in.Read_long();
                        break;
                    case 3:
                        levelFrame = _in.Read_int();
                        break;
                    case 4:
                        m_playerSaves = _in.Read_map_long_pod<LevelPlayerSavePOD>(LevelPlayerSavePOD.DynamicFactory);
                        break;
                    case 5:
                        m_regionSaves = _in.Read_map_int_pod<LevelRegionSavePOD>(LevelRegionSavePOD.DynamicFactory);
                        break;
                    case 6:
                        m_levelParams = _in.Read_map_int_int();
                        break;
                    case 7:
                        m_delayServices = _in.Read_list_pod<DelayServicePOD>(DelayServicePOD.DynamicFactory);
                        break;
                    case 8:
                        timeHour = _in.Read_int();
                        break;
                    case 9:
                        cid = _in.Read_int();
                        break;
                    case 10:
                        hostPlayerId = _in.Read_long();
                        break;
                    case 11:
                        id = _in.Read_long();
                        break;
                    default: _in.SkipBinary();break;
                }
            }
        }
		
		public LevelSavePOD Clone() {
            LevelSavePOD o = DynamicFactory();
            o.idGenerator = idGenerator;
            o.randomSeed = randomSeed;
            o.levelFrame = levelFrame;
            if (m_playerSaves != null) {
                o.m_playerSaves = new ();
				m_playerSaves.ToList().ForEach(kv => o.m_playerSaves.Add(kv.Key, kv.Value?.Clone()));
            }
            if (m_regionSaves != null) {
                o.m_regionSaves = new ();
				m_regionSaves.ToList().ForEach(kv => o.m_regionSaves.Add(kv.Key, kv.Value?.Clone()));
            }
            if (m_levelParams != null) {
                o.m_levelParams = new (m_levelParams);
            }
            if (m_delayServices != null) {
                o.m_delayServices = m_delayServices.ConvertAll(o => o?.Clone());
            }
            o.timeHour = timeHour;
            o.cid = cid;
            o.hostPlayerId = hostPlayerId;
            o.id = id;
            return o;
        }
        
        public void Clear() {
            idGenerator = default;
            randomSeed = default;
            levelFrame = default;
            m_playerSaves = default;
            m_regionSaves = default;
            m_levelParams = default;
            m_delayServices = default;
            timeHour = default;
            cid = default;
            hostPlayerId = default;
            id = default;
        }
		
        public override string ToString() {
			string str = "";
			str += "LevelSavePOD [";
			str += "idGenerator=";
			str += idGenerator;
			str += ", randomSeed=";
			str += randomSeed;
			str += ", levelFrame=";
			str += levelFrame;
			str += ", playerSaves=";
			str += m_playerSaves.ToString<long, LevelPlayerSavePOD>();
			str += ", regionSaves=";
			str += m_regionSaves.ToString<int, LevelRegionSavePOD>();
			str += ", levelParams=";
			str += m_levelParams.ToString<int, int>();
			str += ", delayServices=";
			str += m_delayServices.ToString<DelayServicePOD>();
			str += ", timeHour=";
			str += timeHour;
			str += ", cid=";
			str += cid;
			str += ", hostPlayerId=";
			str += hostPlayerId;
			str += ", id=";
			str += id;
			str += "]";
			return str;
		}
		
	}
}